package com.nickstumpos.android.easyVolume.events.presentation;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.codec.binary.Base64;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CompoundButton.OnCheckedChangeListener;

import com.nickstumpos.android.easyVolume.R;
import com.nickstumpos.android.easyVolume.constants.EVCONSTANTS;
import com.nickstumpos.android.easyVolume.events.Dto.EventTriggerDto;
import com.nickstumpos.android.easyVolume.events.service.EventTriggerService;
import com.nickstumpos.android.easyVolume.events.util.EventServiceUtil;
import com.nickstumpos.android.easyVolume.preset.types.PresetIdentifier;

public class EventTriggeredPresetActivity extends Activity implements
		OnCheckedChangeListener, OnItemSelectedListener {

	private SharedPreferences					settings;
	private SharedPreferences.Editor	editor;
	private EventTriggerDto						edo;
	private Spinner										hsConnectSpinner;
	private Spinner										hsDisconnectSpinner;
	private Spinner										btConnectSpinner;
	private Spinner										btDisconnectSpinner;
	private Spinner										onBootSpinner;
	private List<PresetIdentifier>		hsConnectList;
	private List<PresetIdentifier>		hsDisconnectList;
	private List<PresetIdentifier>		btConnectList;
	private List<PresetIdentifier>		btDisconnectList;
	private List<PresetIdentifier>		onBootList;
	private CheckBox									hsConnectCheckBox;
	private CheckBox									hsDisconnectCheckBox;
	private CheckBox									btConnectCheckBox;
	private CheckBox									btDisconnectCheckBox;
	private CheckBox									onBootCheckBox;

	private void assignViews() {
		this.hsConnectSpinner = (Spinner) this.findViewById(R.id.presetSpinner01);
		this.hsDisconnectSpinner = (Spinner) this
				.findViewById(R.id.presetSpinner02);
		this.btConnectSpinner = (Spinner) this.findViewById(R.id.presetSpinner03);
		this.btDisconnectSpinner = (Spinner) this
				.findViewById(R.id.presetSpinner04);
		this.onBootSpinner = (Spinner) this.findViewById(R.id.presetSpinner05);
		this.hsConnectCheckBox = (CheckBox) this.findViewById(R.id.presetActive01);
		this.hsDisconnectCheckBox = (CheckBox) this
				.findViewById(R.id.presetActive02);
		this.btConnectCheckBox = (CheckBox) this.findViewById(R.id.presetActive03);
		this.btDisconnectCheckBox = (CheckBox) this
				.findViewById(R.id.presetActive04);
		this.onBootCheckBox = (CheckBox) this
				.findViewById(R.id.presetActive05);
	}

	private void onChange() {
		this.edo.setBtConnectActive(this.btConnectCheckBox.isChecked());
		this.edo.setBtDisconnectActive(this.btDisconnectCheckBox.isChecked());
		this.edo.setHsConnectActive(this.hsConnectCheckBox.isChecked());
		this.edo.setHsDisconnectActive(this.hsDisconnectCheckBox.isChecked());
		this.edo.setOnBootActive(this.onBootCheckBox.isChecked());
		if (this.hsConnectSpinner.getSelectedItemId() < this.hsConnectList.size()) {
			this.edo.setHsConnectPreset(this.hsConnectList
					.get((int) this.hsConnectSpinner.getSelectedItemId()));
		} else {
			this.edo.setHsConnectPreset(null);
		}
		if (this.hsDisconnectSpinner.getSelectedItemId() < this.hsDisconnectList
				.size()) {
			this.edo.setHsDisconnectPreset(this.hsDisconnectList
					.get((int) this.hsDisconnectSpinner.getSelectedItemId()));
		} else {
			this.edo.setHsDisconnectPreset(null);
		}
		if (this.btConnectSpinner.getSelectedItemId() < this.btConnectList.size()) {
			this.edo.setBtConnectPreset(this.btConnectList
					.get((int) this.btConnectSpinner.getSelectedItemId()));
		} else {
			this.edo.setBtConnectPreset(null);
		}
		if (this.btDisconnectSpinner.getSelectedItemId() < this.btDisconnectList
				.size()) {
			this.edo.setBtDisconnectPreset(this.btDisconnectList
					.get((int) this.btDisconnectSpinner.getSelectedItemId()));
		} else {
			this.edo.setBtDisconnectPreset(null);
		}
		if (this.onBootSpinner.getSelectedItemId() < this.onBootList
				.size()) {
			this.edo.setOnBootPreset(this.onBootList
					.get((int) this.onBootSpinner.getSelectedItemId()));
		} else {
			this.edo.setOnBootPreset(null);
		}
		final Base64 encoder = new Base64();
		final ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream out = null;
		try {
			out = new ObjectOutputStream(bos);
			out.writeObject(this.edo);
			out.close();
			final byte[] byteParameter = encoder.encode(bos.toByteArray());
			String serialParameter = new String(byteParameter);
			serialParameter = serialParameter.replace("\n", "");
			serialParameter = serialParameter.replace("\r", "");
			this.editor.putString(EVCONSTANTS.EVENT_SCHED_DTO, serialParameter);
			this.editor.commit();
		} catch (final IOException e) {
			Toast.makeText(this, "Saving event presets failed", Toast.LENGTH_SHORT)
					.show();
		}
		if(EventServiceUtil.shouldStartService(edo)){
			this.startService(new Intent(this,EventTriggerService.class));
		}else{
			this.stopService(new Intent(this,EventTriggerService.class));
		}
	}

	@Override
	public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
		this.onChange();

	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.edo = new EventTriggerDto();
		this.setContentView(R.layout.eventschedule);
		this.settings = this.getSharedPreferences(EVCONSTANTS.PREFS_NAME, 0);
		this.editor = this.settings.edit();
		this.assignViews();
		this.setupSpinners();
		String old = this.settings.getString(EVCONSTANTS.EVENT_SCHED_DTO, null);
		if (old != null) {
			final byte[] buf = Base64.decodeBase64(old.getBytes());
			ObjectInputStream in = null;
			try {
				in = new ObjectInputStream(new ByteArrayInputStream(buf));
				EventTriggerDto inflated = (EventTriggerDto) in.readObject();
				this.setupViews(inflated);
			} catch (final IOException e) {
			} catch (final ClassNotFoundException e) {
			}
		}
		this.setListeners();
	}

	@Override
	public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		this.onChange();

	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		boolean ret = false;
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			this.finish();
			ret = true;
		} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
			ret = true;
		} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
			ret = true;
		} else {
			ret = super.onKeyDown(keyCode, event);
		}
		return ret;
	}

	@Override
	public void onNothingSelected(AdapterView<?> arg0) {
		this.onChange();
	}

	private void setListeners() {
		this.hsConnectSpinner.setOnItemSelectedListener(this);
		this.hsDisconnectSpinner.setOnItemSelectedListener(this);
	
		this.onBootSpinner.setOnItemSelectedListener(this);
		this.hsConnectCheckBox.setOnCheckedChangeListener(this);
		this.hsDisconnectCheckBox.setOnCheckedChangeListener(this);
		this.onBootCheckBox.setOnCheckedChangeListener(this);
		try {
			Class.forName("android.bluetooth.BluetoothDevice");
			this.btConnectSpinner.setOnItemSelectedListener(this);
			this.btDisconnectSpinner.setOnItemSelectedListener(this);
			this.btConnectCheckBox.setOnCheckedChangeListener(this);
			this.btDisconnectCheckBox.setOnCheckedChangeListener(this);
		} catch (ClassNotFoundException e) {
			this.btConnectSpinner.setVisibility(View.GONE);
			this.btDisconnectSpinner.setVisibility(View.GONE);
			this.btConnectCheckBox.setVisibility(View.GONE);
			this.btDisconnectCheckBox.setVisibility(View.GONE);
			findViewById(R.id.TextView07).setVisibility(View.GONE);
			findViewById(R.id.TextView08).setVisibility(View.GONE);
		}
	}

	private List<PresetIdentifier> setupSpinner(
			Spinner spinner) {
		List<PresetIdentifier> presetIdentifiers = new ArrayList<PresetIdentifier>();
		ArrayAdapter<String> presets = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item);
		if (this.settings.getString(PresetIdentifier.ONE.getName(), null) != null) {
			presets.add(this.settings.getString(EVCONSTANTS.ONE_NAME,
					PresetIdentifier.ONE.getName()));
			presetIdentifiers.add(PresetIdentifier.ONE);
		}
		if (this.settings.getString(PresetIdentifier.TWO.getName(), null) != null) {
			presets.add(this.settings.getString(EVCONSTANTS.TWO_NAME,
					PresetIdentifier.TWO.getName()));
			presetIdentifiers.add(PresetIdentifier.TWO);
		}
		if (this.settings.getString(PresetIdentifier.THREE.getName(), null) != null) {
			presets.add(this.settings.getString(EVCONSTANTS.THREE_NAME,
					PresetIdentifier.THREE.getName()));
			presetIdentifiers.add(PresetIdentifier.THREE);
		}
		if (this.settings.getString(PresetIdentifier.FOUR.getName(), null) != null) {
			presets.add(this.settings.getString(EVCONSTANTS.FOUR_NAME,
					PresetIdentifier.FOUR.getName()));
			presetIdentifiers.add(PresetIdentifier.FOUR);
		}
		if (this.settings.getString(PresetIdentifier.FIVE.getName(), null) != null) {
			presets.add(this.settings.getString(EVCONSTANTS.FIVE_NAME,
					PresetIdentifier.FIVE.getName()));
			presetIdentifiers.add(PresetIdentifier.FIVE);
		}
		if (this.settings.getString(PresetIdentifier.SIX.getName(), null) != null) {
			presets.add(this.settings.getString(EVCONSTANTS.SIX_NAME,
					PresetIdentifier.SIX.getName()));
			presetIdentifiers.add(PresetIdentifier.SIX);
		}
		if (presets.isEmpty()) {
			presets.add("No presets set");
			spinner.setEnabled(false);
		}
		spinner.setAdapter(presets);
		return presetIdentifiers;
	}

	private void setupSpinners() {
		this.hsConnectList=this.setupSpinner( this.hsConnectSpinner);
		this.hsDisconnectList=this.setupSpinner( this.hsDisconnectSpinner);
		this.btConnectList=this.setupSpinner( this.btConnectSpinner);
		this.btDisconnectList=this.setupSpinner( this.btDisconnectSpinner);
		this.onBootList=this.setupSpinner( this.onBootSpinner);
	}

	private void setupViews(EventTriggerDto eventTriggerDto) {
		if (this.hsConnectList.contains(eventTriggerDto.getHsConnectPreset())) {
			this.hsConnectSpinner.setSelection(this.hsConnectList
					.indexOf(eventTriggerDto.getHsConnectPreset()));
		} else {
			this.hsConnectSpinner.setSelection(this.hsConnectSpinner.getAdapter()
					.getCount() - 1);
		}
		if (this.hsDisconnectList.contains(eventTriggerDto.getHsDisconnectPreset())) {
			this.hsDisconnectSpinner.setSelection(this.hsConnectList
					.indexOf(eventTriggerDto.getHsDisconnectPreset()));
		} else {
			this.hsDisconnectSpinner.setSelection(this.hsConnectSpinner.getAdapter()
					.getCount() - 1);
		}
		if (this.btConnectList.contains(eventTriggerDto.getBtConnectPreset())) {
			this.btConnectSpinner.setSelection(this.btConnectList
					.indexOf(eventTriggerDto.getBtConnectPreset()));
		} else {
			this.btConnectSpinner.setSelection(this.btConnectSpinner.getAdapter()
					.getCount() - 1);
		}
		if (this.btDisconnectList.contains(eventTriggerDto.getBtDisconnectPreset())) {
			this.btDisconnectSpinner.setSelection(this.btConnectList
					.indexOf(eventTriggerDto.getBtDisconnectPreset()));
		} else {
			this.btDisconnectSpinner.setSelection(this.btConnectSpinner.getAdapter()
					.getCount() - 1);
		}
		if (this.onBootList.contains(eventTriggerDto.getOnBootPreset())) {
			this.onBootSpinner.setSelection(this.onBootList
					.indexOf(eventTriggerDto.getOnBootPreset()));
		} else {
			this.onBootSpinner.setSelection(this.onBootSpinner.getAdapter()
					.getCount() - 1);
		}

		this.hsConnectCheckBox.setChecked(eventTriggerDto.isHsConnectActive());
		this.hsDisconnectCheckBox
				.setChecked(eventTriggerDto.isHsDisconnectActive());
		this.btConnectCheckBox.setChecked(eventTriggerDto.isBtConnectActive());
		this.btDisconnectCheckBox
				.setChecked(eventTriggerDto.isBtDisconnectActive());
		this.onBootCheckBox.setChecked(eventTriggerDto.isOnBootActive());
		this.edo = eventTriggerDto;

	}
}
